package com.longma.server.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.longma.server.dao.AddressTreeDAO;
import com.longma.server.entity.AddressTree;
import com.longma.server.constant.enums.ResponseCode;
import com.longma.server.exception.BusinessException;
import com.longma.server.service.IAddressTreeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Transactional
public class AddressTreeServiceImpl implements IAddressTreeService {

    @Autowired
    private AddressTreeDAO addressTreeDAO;

    /**
     * 更新地址
     * 1、如果地址已经存在、不做任何操作
     * 2、如果地址不存在 新增
     * @param address: 0:省会 1：城市 2：区县
     */
    @Override
    public void updateAddress(String[] address) {
        if(address == null || address.length < 1){
            throw new BusinessException(ResponseCode.PARAM_NOT_VALID.setMessage("address参数不正确"));
        }

        // 获取省/直辖市
        AddressTree province = addressTreeDAO.getOne(Wrappers. <AddressTree>lambdaQuery().
                eq(AddressTree::getName,address[0]));

        if(province == null) {
            province = new AddressTree();
            province.setName(address[0]);
            province.setLevels(0);
            addressTreeDAO.save(province);
        }

        if(address.length >=2) {
            // 获取下一级
            AddressTree city = addressTreeDAO.getOne(Wrappers.<AddressTree>lambdaQuery().
                    eq(AddressTree::getName, address[1]));
            if (city == null) {
                city = new AddressTree();
                city.setName(address[1]);
                city.setLevels(1);
                // 设置父节点
                city.setParentId(province.getId());
                addressTreeDAO.save(city);
            }

            // 再下一级
            if(address.length > 2) {
                AddressTree district = addressTreeDAO.getOne(Wrappers.<AddressTree>lambdaQuery().
                        eq(AddressTree::getName, address[2]));
                if (district == null) {
                    district = new AddressTree();
                    district.setName(address[2]);
                    district.setLevels(2);
                    // 设置父节点
                    district.setParentId(city.getId());
                    addressTreeDAO.save(district);
                }
            }
        }
    }

    /**
     *  根据id获取某个地址节点
     */
    @Override
    public AddressTree getAddressMasterNode(Integer id) {
        return addressTreeDAO.getById(id);
    }

    /**
     *  根据id获取某个地址的子节点地址
     */
    @Override
    public List<AddressTree> getAddressSlaveNodes(Integer id) {
        return addressTreeDAO.list(Wrappers.<AddressTree>lambdaQuery().eq(AddressTree::getParentId,id));
    }

    /**
     * 根据id获取树结构
     */
    @Override
    public AddressTree getAddressTreeById(Integer id) {
        AddressTree parent = addressTreeDAO.getOne(Wrappers. <AddressTree>lambdaQuery().eq(AddressTree::getId, id));
        if(parent == null){
            throw new BusinessException(ResponseCode.PARAM_NOT_VALID.setMessage("id不存在"));
        }
        List<AddressTree> children = addressTreeDAO.list(Wrappers. <AddressTree>lambdaQuery().eq(AddressTree::getParentId, id));
        parent.setChildren(children);
        return parent;
    }

    /**
     * 全量表查询  获取完整树结构
     */
    @Override
    public List<AddressTree> getAddressTree() {
        // 省会
        List<AddressTree> provinces = addressTreeDAO.list(Wrappers. <AddressTree>lambdaQuery().eq(AddressTree::getLevels,0));
        if(CollUtil.isEmpty(provinces)){
            return new ArrayList<>();
        }

        // 城市
        List<AddressTree> cities = addressTreeDAO.list(Wrappers. <AddressTree>lambdaQuery().eq(AddressTree::getLevels,1));

        // 分组
        Map<Integer, List<AddressTree>> cityGroup = cities.stream().collect(Collectors.groupingBy(AddressTree::getParentId));
        provinces.forEach(t -> t.setChildren(cityGroup.get(t.getId())));
        return provinces;
    }
}
